using MediatR;
using ProduceBasicData.Api.Application.Command.WorkOrderProgress;
using ProduceBasicData.Api.DTO;
using ProduceBasicData.Domain.FactoryModeling;
using ProduceBasicData.Domain.Material;
using ProduceBasicData.Domain.ProductionManage;
using ProduceBasicData.ErrorCode;
using ProduceBasicData.Infrastructure.Interface;

namespace ProduceBasicData.Api.Application.Handler.WorkOrderProgress
{
    /// <summary>
    /// 获取工单实时进度处理类
    /// </summary>
    public class GetWorkOrderProgressHandler : IRequestHandler<GetWorkOrderProgressCommand, ApiResult<WorkOrderProgressChartDto>>
    {
        private readonly IBaseRespository<Work_order> _workOrderRepository;
        private readonly IBaseRespository<Production_report> _productionReportRepository;
        private readonly IBaseRespository<Report_Record> _reportRecordRepository;
        private readonly IBaseRespository<ClientModel> _clientRepository;
        private readonly IBaseRespository<ProductMaterialModel> _productRepository;

        public GetWorkOrderProgressHandler(
            IBaseRespository<Work_order> workOrderRepository,
            IBaseRespository<Production_report> productionReportRepository,
            IBaseRespository<Report_Record> reportRecordRepository,
            IBaseRespository<ClientModel> clientRepository,
            IBaseRespository<ProductMaterialModel> productRepository)
        {
            _workOrderRepository = workOrderRepository;
            _productionReportRepository = productionReportRepository;
            _reportRecordRepository = reportRecordRepository;
            _clientRepository = clientRepository;
            _productRepository = productRepository;
        }

        public async Task<ApiResult<WorkOrderProgressChartDto>> Handle(GetWorkOrderProgressCommand request, CancellationToken cancellationToken)
        {
            ApiResult<WorkOrderProgressChartDto> result = new ApiResult<WorkOrderProgressChartDto>();

            try
            {
                var chartData = new WorkOrderProgressChartDto();

                // 获取工单数据
                var workOrders = _workOrderRepository.GetAll()
                    .Where(x => !x.Isdel);

                // 应用筛选条件
                if (!string.IsNullOrEmpty(request.OrderNo))
                {
                    workOrders = workOrders.Where(x => x.Order_no.Contains(request.OrderNo));
                }

                if (request.Status.HasValue)
                {
                    workOrders = workOrders.Where(x => x.Status == request.Status.Value);
                }

                if (request.CustomerId.HasValue)
                {
                    workOrders = workOrders.Where(x => x.Customer_id == request.CustomerId.Value);
                }

                if (request.ProductId.HasValue)
                {
                    workOrders = workOrders.Where(x => x.Product_id == request.ProductId.Value);
                }

                if (request.ProductionId.HasValue)
                {
                    workOrders = workOrders.Where(x => x.Producttion_id == request.ProductionId.Value);
                }

                if (request.StartDate.HasValue)
                {
                    workOrders = workOrders.Where(x => x.Start_time >= request.StartDate.Value);
                }

                if (request.EndDate.HasValue)
                {
                    workOrders = workOrders.Where(x => x.End_time <= request.EndDate.Value);
                }

                if (request.OnlyInProgress)
                {
                    workOrders = workOrders.Where(x => x.Status == 3); // 只显示已开工的工单
                }

                // 应用排序
                workOrders = ApplySorting(workOrders, request.SortType, request.SortDirection);

                // 应用分页
                if (request.PageSize > 0)
                {
                    workOrders = workOrders.Take(request.PageSize);
                }

                var workOrderList = workOrders.ToList();

                // 获取客户和产品信息
                var customerIds = workOrderList.Select(x => x.Customer_id).Distinct().ToList();
                var productIds = workOrderList.Select(x => x.Product_id).Distinct().ToList();

                var customers = _clientRepository.GetAll()
                    .Where(x => !x.Isdel && customerIds.Contains(x.Id))
                    .ToDictionary(x => x.Id, x => x.Clientname);

                var products = _productRepository.GetAll()
                    .Where(x => !x.Isdel && productIds.Contains(x.Id))
                    .ToDictionary(x => x.Id, x => x.ProductName);

                // 构建工单进度数据
                var workOrderProgressList = new List<WorkOrderProgressDto>();
                int serialNumber = 1;

                foreach (var workOrder in workOrderList)
                {
                    var progressData = await CalculateWorkOrderProgress(workOrder);
                    
                    var workOrderProgress = new WorkOrderProgressDto
                    {
                        SerialNumber = serialNumber++,
                        WorkOrderId = workOrder.Id,
                        OrderNo = workOrder.Order_no,
                        WorkType = workOrder.Work_type,
                        Status = workOrder.Status,
                        StatusName = GetStatusName(workOrder.Status),
                        StatusProgress = GetStatusProgress(workOrder.Status),
                        StatusColor = GetStatusColor(workOrder.Status),
                        ProgressPercentage = progressData.ProgressPercentage,
                        TotalQuantity = workOrder.Order_number,
                        CompletedQuantity = progressData.CompletedQuantity,
                        StartTime = workOrder.Start_time,
                        EndTime = workOrder.End_time,
                        ActualStartTime = progressData.ActualStartTime,
                        ActualEndTime = progressData.ActualEndTime,
                        ProductName = products.ContainsKey(workOrder.Product_id) ? products[workOrder.Product_id] : "",
                        CustomerName = customers.ContainsKey(workOrder.Customer_id) ? customers[workOrder.Customer_id] : ""
                    };

                    workOrderProgressList.Add(workOrderProgress);
                }

                chartData.WorkOrders = workOrderProgressList;

                // 计算统计信息
                chartData.Statistics = CalculateStatistics(workOrderProgressList);

                // 构建图表数据
                if (request.IncludeChartData)
                {
                    chartData.ChartData = BuildChartData(workOrderProgressList);
                }

                result.Code = ApiEnum.Success;
                result.Msg = "查询成功";
                result.Data = chartData;
            }
            catch (Exception ex)
            {
                result.Code = ApiEnum.Failed;
                result.Msg = $"查询失败：{ex.Message}";
                result.Data = new WorkOrderProgressChartDto();
            }

            return result;
        }

        /// <summary>
        /// 计算工单进度
        /// </summary>
        private async Task<(decimal ProgressPercentage, int CompletedQuantity, DateTime? ActualStartTime, DateTime? ActualEndTime)> CalculateWorkOrderProgress(Work_order workOrder)
        {
            // 获取该工单的生产报工记录
            var productionReports = _productionReportRepository.GetAll()
                .Where(x => !x.Isdel && x.Order_id == workOrder.Id)
                .ToList();

            // 获取该工单的报工记录 - 修复LINQ翻译问题
            var reportNumbers = productionReports.Select(pr => pr.Report_no).ToList();
            var reportRecords = _reportRecordRepository.GetAll()
                .Where(x => !x.Isdel && reportNumbers.Contains(x.Report_no))
                .ToList();

            // 计算已完成数量
            var completedQuantity = reportRecords.Sum(x => x.Report_qty);

            // 计算进度百分比
            var progressPercentage = workOrder.Order_number > 0 
                ? Math.Min(100, Math.Round((decimal)completedQuantity / workOrder.Order_number * 100, 2))
                : 0;

            // 获取实际开始和结束时间
            var actualStartTime = productionReports.Any() ? productionReports.Min(x => x.Production_time) : (DateTime?)null;
            var actualEndTime = workOrder.Status == 4 && productionReports.Any() 
                ? productionReports.Max(x => x.Production_time) 
                : (DateTime?)null;

            return (progressPercentage, completedQuantity, actualStartTime, actualEndTime);
        }

        /// <summary>
        /// 获取状态名称 1初始化0%,2待审批,3已下发,4已完成,5领料中,6领料完成
        /// </summary>
        private string GetStatusName(int status)
        {
            return status switch
            {
                1 => "初始化",
                2 => "待审批",
                3 => "已开工",
                4 => "已完工",
                5 => "领料中",
                6 => "领料完成",
                _ => "未知"
            };
        }

        /// <summary>
        /// 获取状态进度百分比
        /// </summary>
        private int GetStatusProgress(int status)
        {
            return status switch
            {
                1 => 10,
                2 => 20,
                3 => 50,
                4 => 100,
                _ => 0
            };
        }

        /// <summary>
        /// 获取状态颜色
        /// </summary>
        private string GetStatusColor(int status)
        {
            return status switch
            {
                1 => "#909399", // 灰色
                2 => "#E6A23C", // 橙色
                3 => "#409EFF", // 蓝色
                4 => "#67C23A", // 绿色
                _ => "#909399"
            };
        }

        /// <summary>
        /// 应用排序
        /// </summary>
        private IQueryable<Work_order> ApplySorting(IQueryable<Work_order> query, int sortType, int sortDirection)
        {
            return sortType switch
            {
                1 => sortDirection == 1 ? query.OrderBy(x => x.Order_no) : query.OrderByDescending(x => x.Order_no),
                2 => sortDirection == 1 ? query.OrderBy(x => x.Status) : query.OrderByDescending(x => x.Status),
                3 => sortDirection == 1 ? query.OrderBy(x => x.Order_number) : query.OrderByDescending(x => x.Order_number),
                4 => sortDirection == 1 ? query.OrderBy(x => x.CreateTime) : query.OrderByDescending(x => x.CreateTime),
                _ => query.OrderByDescending(x => x.CreateTime)
            };
        }

        /// <summary>
        /// 计算统计信息
        /// </summary>
        private WorkOrderProgressStatistics CalculateStatistics(List<WorkOrderProgressDto> workOrders)
        {
            var statistics = new WorkOrderProgressStatistics
            {
                TotalWorkOrders = workOrders.Count,
                CompletedWorkOrders = workOrders.Count(x => x.Status == 4),
                InProgressWorkOrders = workOrders.Count(x => x.Status == 3),
                PendingWorkOrders = workOrders.Count(x => x.Status == 2),
                TotalProductionQuantity = workOrders.Sum(x => x.TotalQuantity),
                CompletedProductionQuantity = workOrders.Sum(x => x.CompletedQuantity)
            };

            statistics.OverallCompletionRate = statistics.TotalProductionQuantity > 0
                ? Math.Round((decimal)statistics.CompletedProductionQuantity / statistics.TotalProductionQuantity * 100, 2)
                : 0;

            return statistics;
        }

        /// <summary>
        /// 构建图表数据
        /// </summary>
        private WorkOrderProgressChartData BuildChartData(List<WorkOrderProgressDto> workOrders)
        {
            return new WorkOrderProgressChartData
            {
                OrderNumbers = workOrders.Select(x => x.OrderNo).ToList(),
                ProgressPercentages = workOrders.Select(x => x.ProgressPercentage).ToList(),
                StatusNames = workOrders.Select(x => x.StatusName).ToList(),
                StatusColors = workOrders.Select(x => x.StatusColor).ToList()
            };
        }
    }
}
